<template>
  <div class="role-sql-authorization">
    <div class="content">
      <div class="top">
        角色SQL授权：
        <je-select
          v-model:value="SQLValue"
          :style="{ marginRight: '100px' }"
          :options="SQLOptions"
          :allow-clear="false"
        ></je-select>
        授权范围：
        <je-select
          v-model:value="authorizationValue"
          :disabled="disabled"
          :options="authorizationOptions"
          :allow-clear="false"
          @change="changeEvent"
        ></je-select>
      </div>
      <div class="warp">
        <div class="left">
          <div class="title">{{ title }}</div>
          <div class="panel">
            <je-tree
              ref="treeview"
              class="table-treeView"
              :search="false"
              :tree-config="{
                trigger: 'cell-dblclick',
                rowField: 'id',
                parentField: 'parent',
                expandAll: true,
              }"
              :checkbox-config="{
                checkMethod: ({ row }) => {
                  return !disabled && row.bean.ROLE_TYPE_CODE !== 'folder';
                },
                checkStrictly: true,
                cascadeChild: false,
                cascadeParent: false,
              }"
              :loading="loading"
              size="mini"
              :data="treeData"
              multiple
              @checkbox-change="handlerSelect"
            >
              <template #nodeIcon="{ row }">
                <i
                  v-if="row.bean.ROLE_TYPE_CODE === 'folder' && row.children.length === 0"
                  class="is--folder fas fa-folder"
                ></i>
              </template>
            </je-tree>
          </div>
        </div>
        <div class="right">
          <div class="text"
            ><je-text-area v-model:value="value" :disabled="disabled" class="my-textarea">
            </je-text-area
          ></div>
          <div class="cover"
            ><je-switch
              v-model:value="coverValue"
              :disabled="disabled"
              mode="checkbox"
            />&nbsp;&nbsp;覆盖原功能WhereSql</div
          >
        </div>
      </div>
    </div>
    <div class="footer">
      <je-button type="primary" :disabled="btnDisabled" class="btn" @click="save"
        >保存刷新</je-button
      >
      <je-button class="btn" :disabled="disabled || btnDisabled" @click="reset">恢复数据</je-button>
      <je-button class="btn" @click="closeEvent">关闭</je-button>
    </div>
  </div>
</template>

<script>
  import { defineComponent, onMounted, ref, watch } from 'vue';

  import { Button, Select, Input, Switch, Tree, Modal } from '@jecloud/ui';

  import { isNotEmpty, isEmpty } from '@jecloud/utils';

  import {
    doSaveApi,
    getPremDataApi,
    loadDepartmentTreeApi,
    loadOrgApi,
    loadRoleTreeApi,
  } from '@/api/authorization';

  import { useDialog } from '@/hooks/use-dialog';

  import {
    JE_DATAAUTHORITY_RSAAUTHORIZATIONOPTIONS,
    JE_DATAAUTHORITY_RSASQLOOPTIONS,
  } from '@/helper/constant';

  export default defineComponent({
    name: 'RoleSQLAuthorization',
    components: {
      JeButton: Button,
      JeTextArea: Input.TextArea,
      JeSelect: Select,
      JeSwitch: Switch,
      JeTree: Tree,
    },
    props: {
      currentFuncId: {
        type: String,
        default: '',
      },
      currentFuncCode: {
        type: String,
        default: '',
      },
      parentModal: String,
    },
    emits: ['isChange'],
    setup(props, { emit }) {
      const treeData = ref([]); // tree的数据
      const treeview = ref('treeview'); // 树的实例
      const loading = ref(false);

      const title = ref('角色SQL权限'); // 标题

      const SQLValue = ref('0'); // SQL值
      // SQL选项
      const SQLOptions = JE_DATAAUTHORITY_RSASQLOOPTIONS;
      const authorizationValue = ref('0'); // 授权值
      // 授权选项
      const authorizationOptions = JE_DATAAUTHORITY_RSAAUTHORIZATIONOPTIONS;

      const value = ref(''); // 文本框值
      const coverValue = ref('0'); // 覆盖原功能WhereSql值
      const disabled = ref(true); // 展示有功能授权的所有角色值
      let meta = { value: '', coverValue: '0' }; //对比项
      let metaOpen = '0'; //对比项
      const btnDisabled = ref(false); // 按钮禁用

      // 页面所有数据
      const allData = ref([]);
      // 传参
      const payloadData = ref({
        roleSqlAuthDeptList: [],
        roleSqlAuthOrgList: [],
        roleSqlAuthRoleList: [],
      });

      // 请求对象
      const apiObj = {
        loadRoleTree: loadRoleTreeApi(), // 角色树
        loadDeptTree: loadDepartmentTreeApi(), // 部门树
        loadOrgTree: loadOrgApi({ excludeDepartment: '1' }), // 机构树
      };

      // 切换得到左侧树
      const getTreeData = (param) => {
        // 重置数据
        restAllData();
        loading.value = true;
        // 调用相应接口
        apiObj[param].then((res) => {
          treeData.value = res.children;
          loading.value = false;
          setTimeout(() => {
            treeData.value.forEach((item) => {
              // 展开
              const row = treeview.value.getRowById(item.id);
              treeview.value.setTreeExpand(row, true);
              btnDisabled.value = false;
            });
          }, 200);
        });
      };

      // 选择授权范围
      const changeEvent = (e) => {
        btnDisabled.value = true;
        if (e === '0') {
          // 角色
          title.value = '角色SQL权限';
          getTreeData('loadRoleTree');
        } else if (e === '1') {
          // 部门
          title.value = '部门SQL权限';
          getTreeData('loadDeptTree');
        } else if (e === '2') {
          // 机构
          title.value = '机构SQL权限';
          getTreeData('loadOrgTree');
        }
      };

      const funcId = ref(''); // id
      const funcCode = ref(''); // code

      // 保存
      const save = () => {
        // 数据发生改变才允许保存
        if (isChange()) return Modal.notice('无数据操作!', 'info');
        btnDisabled.value = true;
        // 获取改变的数据
        getSaveData();
        // 调用保存接口
        doSaveApi({
          tableCode: 'JE_CORE_FUNCPERM',
          FUNCPERM_FUNCINFO_CODE: funcCode.value,
          FUNCPERM_FUNCINFO_ID: funcId.value,
          FUNCPERM_TYPE: 'roleSqlAuth',
          FUNCPERM_ON_OFF: SQLValue.value,
          FUNCPERM_CONFIG: JSON.stringify(payloadData.value),
        }).then((res) => {
          Modal.notice(res.message, 'success');
          btnDisabled.value = false;
          // 重新load
          GetPremData('roleSqlAuth', 'falg');
          // 给对照组重新赋值
          if (SQLValue.value) {
            metaOpen = JSON.parse(JSON.stringify(SQLValue.value));
          }
          if (value.value) {
            meta.value = JSON.parse(JSON.stringify(value.value));
          } else {
            meta.value = '';
          }
          if (coverValue.value) {
            meta.coverValue = JSON.parse(JSON.stringify(coverValue.value));
          }
        });
      };

      // 得到保存数据
      const getSaveData = () => {
        // 得到所有选中项
        const nowData = treeview.value.getCheckboxRecords(true);
        allData.value = [];
        // 转化数据
        nowData.forEach((item) => {
          const obj = {};
          obj['coverSql'] = coverValue.value || '0';
          obj['id'] = item.id;
          obj['sql'] = value.value;
          allData.value.push(obj);
        });
        // 赋值
        if (title.value === '角色SQL权限') {
          payloadData.value.roleSqlAuthRoleList = JSON.parse(JSON.stringify(allData.value));
        } else if (title.value === '部门SQL权限') {
          payloadData.value.roleSqlAuthDeptList = JSON.parse(JSON.stringify(allData.value));
        } else {
          payloadData.value.roleSqlAuthOrgList = JSON.parse(JSON.stringify(allData.value));
        }
      };

      // 回显
      onMounted(() => {
        funcId.value = props.currentFuncId;
        funcCode.value = props.currentFuncCode;
        loading.value = true;
        btnDisabled.value = true;
        GetPremData('roleSqlAuth');
      });

      // 选中row的id的集合
      let row1 = [];
      // 点击事件
      let formerSql = '';
      const handlerSelect = ({ row }) => {
        // 文件夹分类不作操作
        if (row.bean.ROLE_TYPE_CODE === 'folder') {
          return false;
        }
        // 不存在才放入
        if (!row1.includes(row.id)) {
          row1.push(row.id);
        } else {
          // 否则删除该项
          const index = row1.findIndex((item) => {
            return item === row.id;
          });
          row1.splice(index, 1);
        }
        // 显示第一项
        if (title.value === '角色SQL权限') {
          setResult('roleSqlAuthRoleList', row1[0]);
        } else if (title.value === '部门SQL权限') {
          setResult('roleSqlAuthDeptList', row1[0]);
        } else {
          setResult('roleSqlAuthOrgList', row1[0]);
        }
      };

      // 请求回显值
      const GetPremData = (target, falg) => {
        getPremDataApi({
          tableCode: 'JE_CORE_FUNCPERM',
          FUNCPERM_FUNCINFO_ID: funcId.value,
          FUNCPERM_TYPE: target,
        }).then((res) => {
          // 不存在falg数据才允许更新
          if (!falg) {
            treeData.value = res[0].values?.roleTree?.children;
          }
          btnDisabled.value = false;
          if (res[0]?.values) {
            if (res[0]?.values?.FUNCPERM_CONFIG) {
              // payloadData赋值
              payloadData.value = JSON.parse(res[0]?.values?.FUNCPERM_CONFIG);
            }
            // SQLValue.value赋值
            SQLValue.value = res[0]?.values?.FUNCPERM_ON_OFF || '0';
            if (SQLValue.value) {
              // 打开对比项赋值
              metaOpen = JSON.parse(JSON.stringify(SQLValue.value));
            }
          }
          loading.value = false;
          setTimeout(() => {
            treeData.value.forEach((item) => {
              // 展开所有项
              const row = treeview.value.getRowById(item.id);
              treeview.value.setTreeExpand(row, true);
            });
          }, 130);
        });
      };

      // 赋值
      const setResult = (target, id) => {
        const res = payloadData.value[target];
        // 得到相应所需数据
        let result = [];
        if (res) {
          result = res.filter((item) => {
            return item.id === id;
          });
        }
        /* 勾选、取消勾选
          都获取了 第一个勾选的数据，将该数据 与右侧窗口数据进行对比，
          若一致，则 获取新的第一个勾选的数据 覆盖右侧数据。
          若不一致，则 获取新的第一个勾选的数据 不覆盖右侧数据。 */
        // 是否覆盖
        if (isNotEmpty(result[0])) {
          coverValue.value = result[0]?.coverSql || '0';
        }
        // 文本框值值
        if ((isNotEmpty(result[0]) && formerSql == value.value) || isEmpty(value.value)) {
          formerSql = value.value = result[0]?.sql || '';
        }
        const nowData = treeview.value.getCheckboxRecords(true);
        if (nowData.length <= 0) {
          value.value = '';
          coverValue.value = '0';
        }
        // 对比项赋值
        if (value.value) {
          meta.value = JSON.parse(JSON.stringify(value.value));
        } else {
          meta.value = '';
        }
        if (coverValue.value) {
          meta.coverValue = JSON.parse(JSON.stringify(coverValue.value));
        }
      };

      // SQLValue的值控制禁用状态
      watch(
        () => SQLValue.value,
        (nv) => {
          disabled.value = nv === '0';
        },
        { immediate: true },
      );

      // 清除数据
      const restAllData = () => {
        allData.value = [];
        value.value = '';
        coverValue.value = '0';
        row1 = [];
      };

      // 对比是否的改变
      const isChange = () => {
        // 获取当前已选中的行数据
        const nowData = treeview.value.getCheckboxRecords(true);
        let bool1 = true;
        let bool2 = true;
        let bool3 = true;
        const res3 = metaOpen === SQLValue.value; // 可操作已打开
        if (nowData.length > 0) {
          bool1 = meta.value === value.value; // 文本框的值是否改变
          bool2 = meta.coverValue === coverValue.value; // 允许覆盖的值是否改变
          // 根据所选项进行对比
          if (title.value === '角色SQL权限') {
            bool3 = contrastData('roleSqlAuthRoleList', bool3);
          } else if (title.value === '部门SQL权限') {
            bool3 = contrastData('roleSqlAuthDeptList', bool3);
          } else {
            bool3 = contrastData('roleSqlAuthOrgList', bool3);
          }
        }
        return bool1 && bool2 && bool3 && res3;
      };
      // 新旧值对比
      const contrastData = (target, bool3) => {
        let bool = bool3;
        const arr = [];
        // 回显数据的id集合
        payloadData.value[target].forEach((item) => {
          arr.push(item.id);
        });
        // 点击项的id集合
        const res2 = row1.every((x) => {
          return arr.includes(x);
        });
        if (!res2) {
          return (bool = false);
        }
        // 得到payloadData和row1的交集
        const result = payloadData.value[target].filter((item) => {
          return row1.includes(item.id);
        });
        // 如果每一项都与页面上的值一致是说明数据未发生改变
        bool = result.every((item) => {
          return item.coverSql === coverValue.value && item.sql === value.value;
        });
        return bool;
      };

      // 恢复数据
      const reset = () => {
        Modal.confirm('您确定要恢复数据吗？', () => {
          toReset();
        });
      };

      // 重置数据
      const toReset = () => {
        // SQLValue.value = JSON.parse(JSON.stringify(metaOpen));
        meta.value = '';
        meta.coverValue = '0';
        if (title.value === '角色SQL权限') {
          GetPremData('roleSqlAuth', 'falg');
        } else if (title.value === '部门SQL权限') {
          GetPremData('roleSqlAuth', 'falg');
        } else {
          GetPremData('roleSqlAuth', 'falg');
        }
        restAllData();
        treeview.value.clearCheckboxRow();
      };

      // 切换tab的回调
      const changeTabCb = () => {
        const flag = isChange();
        if (flag) return emit('isChange', flag);
        setTimeout(() => {
          // 弹框
          useDialog({ toReset, save, isDicOrRole: true });
        }, 0);
      };

      // 关闭
      const closeEvent = () => {
        props.parentModal.close();
      };

      return {
        SQLValue,
        SQLOptions,
        authorizationValue,
        authorizationOptions,
        value,
        disabled,
        coverValue,
        treeData,
        treeview,
        loading,
        title,
        btnDisabled,
        save,
        changeEvent,
        handlerSelect,
        reset,
        closeEvent,
        changeTabCb,
      };
    },
  });
</script>

<style lang="less" scoped>
  .role-sql-authorization {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 0 20px;
    border: 1px solid #d7d7d7;
    background: #edf0f4;
    justify-content: space-between;
    align-items: start;
    .my-textarea {
      height: 100% !important;
    }
    .footer {
      height: 0px;
      min-height: 70px;
      .btn {
        margin-right: 15px;
        margin-top: 20px;
      }
    }
    .content {
      padding-top: 20px;
      flex: '1';
      height: 100%;
      width: 100%;
      display: flex;
      flex-direction: column;
      .top {
        padding-left: 16px;
        width: 100%;
        height: 50px;
        background: #ffffff;
        line-height: 50px;
      }
      .warp {
        flex: 1;
        margin-top: 8px;
        display: flex;
        .left {
          display: flex;
          flex-direction: column;
          height: 100%;
          width: 300px;
          margin-right: 8px;
          .title {
            height: 40px;
            background: #fff;
            line-height: 40px;
            text-align: center;
            margin-bottom: 2px;
          }
          .panel {
            flex: 1;
            background: #fff;
          }
        }
        .right {
          flex: 1;
          display: flex;
          flex-direction: column;
          height: 100%;
          .text {
            flex: 1;
            background: #fff;
            padding: 10px;
          }
          .cover {
            margin-top: 8px;
            height: 40px;
            line-height: 40px;
            background: #fff;
            padding-left: 16px;
          }
        }
      }
    }
  }
</style>
